/*
   Copyright (C) 2008 Yen-Ju Chen <yjchenx gmail>

   This application is free software; you can redistribute it and/or 
   modify it under the terms of the MIT license. See COPYING.

*/

#import "GNUstep.h"
#import "AppController.h"
#import "ICCollectionManager.h"
#import "ICItem.h"
#import "SequenceView.h"
#import <BioCocoa/BCFoundation.h>

static NSString *defaultCollectionIdentifier = @"Library";
static NSString *customCollectionIdentifier = @"Collection";

@interface AppController (Private)
/* This method also reload itemView (NSTableView). */
- (void) refreshItemViewCache;
@end

@implementation AppController

- (IBAction) newSequenceAction: (id) sender
{
	NSLog(@"New Sequence");
	ICItem *item = [[ICItem alloc] init];
	[item setTitle: @"New Sequence"];
	[item setDNASequence: [BCSequence sequenceWithString: @"ATCB"]];
	[collectionManager addItem: item];
	DESTROY(item);
	[self refreshItemViewCache];
}

- (IBAction) deleteSequenceAction: (id) sender
{
	NSLog(@"Delete Sequence");
	NSInteger selectedRow = [itemView selectedRow];
	if (selectedRow == -1)
		return;

	ICItem *item = [itemViewCache objectAtIndex: selectedRow];
	if (item != nil)
	{
		[collectionManager removeItem: item];
		[self refreshItemViewCache];
	}
}

- (IBAction) showMainWindowAction: (id) sender
{
	[mainWindow makeKeyAndOrderFront: sender];
}

- (void) awakeFromNib
{
	[sourceView expandItem: defaultCollectionIdentifier];

	[NSBundle loadNibNamed: @"SequenceView" owner: sequenceView];
	NSRect contentFrame = [contentView bounds];
	[[sequenceView view] setFrame: contentFrame];
	[contentView addSubview: [sequenceView view]];

	[sequenceView setDelegate: self];
}

/* NSApplication */
- (void) applicationWillFinishLaunching: (NSNotification *) not
{
	[collectionManager loadDatabase];
}

- (void) applicationDidFinishLaunching: (NSNotification *) not
{
}

- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication *) app
{
	/* Save database */
	[collectionManager saveDatabase];
	return NSTerminateNow;
}

- (id) init
{
	self = [super init];

  collectionManager = [ICCollectionManager defaultManager];
	sequenceView = [[SequenceView alloc] init];
	itemViewCache = [[NSMutableArray alloc] init];

	return self;
}

- (void) dealloc
{
	/* do not release collectionManager here because it is singleton */
	DESTROY(sequenceView);
	DESTROY(itemViewCache);
	[super dealloc];
}

/** contentView delegate */
- (void) sequenceViewDidFinishEditing: (SequenceView *) sv
{
	/* Save sequence back to file */
	ICItem *item = [sv item];
	if (item)
	{
		[collectionManager saveSequenceOfItem: item];
	}
	[itemView reloadData];
}

- (void) typeDidChangeInSequenceView: (SequenceView *) sv
{
	/* Change type of item  */
	ICItem *item = [sv item];
	if (item)
	{
		[collectionManager organizeItem: item];
	}
	[self refreshItemViewCache];
//	[itemView reloadData];
}

/** itemView data source */

- (NSInteger) numberOfRowsInTableView: (NSTableView *) tv
{
	return [itemViewCache count];
}

- (id) tableView: (NSTableView *) tv 
       objectValueForTableColumn: (NSTableColumn *) tc
       row: (NSInteger) row
{
	ICItem *item = [itemViewCache objectAtIndex: row];
	if ([[tc identifier] isEqualToString: @"title"])
		return [item title];
	if ([[tc identifier] isEqualToString: @"length"])
		return [NSString stringWithFormat: @"%d", [item length]];
	else 
		return @"";
}

- (void) tableView: (NSTableView *) tv 
	       setObjectValue: (id) anObject
         forTableColumn: (NSTableColumn *) tc
         row: (NSInteger) row
{
	ICItem *item = [itemViewCache objectAtIndex: row];
	if (([[tc identifier] isEqualToString: @"title"]) && 
	    ([anObject isKindOfClass: [NSString class]]))
		[item setTitle: anObject];
}

- (void) tableViewSelectionDidChange: (NSNotification *) not
{
  NSInteger selectedIndex = [itemView selectedRow];
	if (selectedIndex == -1)
	{
		[sequenceView setItem: nil];
		return;
	}

	ICItem *item = [itemViewCache objectAtIndex: selectedIndex];
	if (item != nil)
	{
		[sequenceView setItem: item];
	}
}

/** sourceView data source */

- (id) outlineView: (NSOutlineView *) ov
             child: (NSInteger)index 
            ofItem: (id) item
{
	if (item == nil)
	{
		/* root */
		if (index == 0)
			return defaultCollectionIdentifier;
		else
			return customCollectionIdentifier;
	}
	else
	{
		/* Collections */
		if ([item isKindOfClass: [NSString class]])
		{
			if ([item isEqualToString: defaultCollectionIdentifier])
				return [collectionManager defaultCollectionAtIndex: index];
			else
				return [collectionManager customCollectionAtIndex: index];
		}
		else if ([item isKindOfClass: [ICCollection class]])
		{
			NSAssert(NO, @"No child for ICCollection");
		}
		else
		{
			NSAssert(NO, @"Item is not NSString or ICCollection");
		}
	}
	return nil;
}

- (BOOL) outlineView: (NSOutlineView *) outlineView isItemExpandable: (id) item
{
	if ([item isKindOfClass: [NSString class]])
	{
		return YES;
	}
	return NO;
}

- (NSInteger) outlineView: (NSOutlineView *) outlineView 
   numberOfChildrenOfItem: (id) item
{
	if (item == nil)
	{
		/* root */
		return 2; /* Default and Custom */
	}
	else if ([item isKindOfClass: [NSString class]])
	{
		if ([item isEqualToString: defaultCollectionIdentifier])
		{
			return [collectionManager numberOfDefaultCollections];
		}
		else if ([item isEqualToString: customCollectionIdentifier])
		{
			return [collectionManager numberOfCustomCollections];
		}
		else
		{
			NSAssert(NO, @"Item is not NSString");
		}
	}
	return 0;
}

- (id) outlineView: (NSOutlineView *) outlineView 
       objectValueForTableColumn: (NSTableColumn *) tableColumn 
       byItem: (id) item
{
	if ([item isKindOfClass: [NSString class]])
	{
		return _(item);
	}
	else if ([item isKindOfClass: [ICCollection class]])
	{
		return [item title];
	}
	return @"Unknown Item";
}

- (void) outlineViewSelectionDidChange: (NSNotification *) not
{
	[itemView deselectAll: self];
	[self refreshItemViewCache];
}

@end

@implementation AppController (Private)
- (void) refreshItemViewCache
{
	NSInteger selectedRow = [sourceView selectedRow];
	if (selectedRow == -1)
	{
		/* No source is selected. Clear sequence view */
		[sequenceView setItem: nil];
		return;
	}

	id selectedCollection = [sourceView itemAtRow: selectedRow];
	if ([selectedCollection isKindOfClass: [NSString class]])
	{
		/* No item is selected. Clear sequence view */
		[sequenceView setItem: nil];
		return;
	}

	[itemViewCache setArray: [selectedCollection allItems]];
	/* Do sorting here */
	[itemView reloadData];
}
@end
